/**
 * Description:该类主要用于装载容器内的控件， 并对控件进行初始化
 * Copyright: 成都和为科技有限公司 2012
 * 属性：
 *   dataSource - 数据源。对应DataService的id属性
 */
function Container() {}

Container.inherit(Control);

/**
 * 初始化方法
 * @param {Object} g_sPath
 * @param {Object} sName 控件名字
 * @param {Object} obj 控件html对象
 */
Container.prototype.init = function () {
	Container.base.init.call(this);
    this._container = true;
}

Container.prototype.create = function(){
	if(!this._html){
		this._html = document.createElement("div");
	}
}

/**
 * 加载容器内容
 */
Container.prototype.initLoad = function() {
	this.buildDataModel();
	this.buildElements(this.getHTML());
    if (this.getAttribute().disabled == "true") {
        this.setDisable();
    }
    if (this.getAttribute().readonly == "true") {
        this.setReadonly();
    }
}

/**
 * 创建数据模型
 */
Container.prototype.buildDataModel = function() {
	if (this.getDataSource()) {
		this._dataModel = new DataModel(this.getDataSource());
	}
}

Container.prototype.getDataModel = function() {
	return this._dataModel;
}

/**
 * 遍历页面子节点装载控件
 */
Container.prototype.buildElements = function(oElement) {
    var othis = this;
    //依次遍历整个页面节点
    //加载具备data-control自定义控件
    $(oElement).children().each(function(index, element) {
        var control = $(element).data("control");
        if (control) {
            othis.loadControl(control, element);
        } else {
            othis.buildElements(element);
        }
    });
}

/**
 * 加载控件
 * @param {} sType
 * @param {} oAR
 */
Container.prototype.loadControl = function(sType, oElement) {
    var oAttr = new Object();
    for (var i = 0 ; i < oElement.attributes.length ; i++) {
        var atrr = oElement.attributes[i];
        oAttr[atrr.name.toLowerCase()] = atrr.value;
    }
    if(!oAttr.id) {
        oAttr.id = Math.uuid();
    }
    try {
        if (sType == "Script" || sType == "Style" || sType== "HandleClass") return;
        var oControl = Control.newInstance(sType, oAttr);
        oControl.setElement(oElement);
        oControl._elementclone = $(oElement).clone(true)[0]; //复制一个节点,用于clone方法用
        oControl.setParent(this);
        oControl.setRoot(this.getRoot());
        oControl.setComponent(this.getComponent());
        oControl.init();
        this.addElement(oControl);
        oControl.initLoad();
        //IE8需要重新绑定事件
        if (!$.support.leadingWhitespace) {
            oControl.rebuildEvent();
        }
        this.buildDataUnit(oControl);
    } catch(e){
    	if (!console) {
    	      console.error(e);
    	}
    }
}

/**
 * 增加控件
 * @param {} id
 * @param {} oControl
 */
Container.prototype.addElement = function(oControl) {
	var id = oControl.getAttribute().id;
	if (!this._elements) this._elements = new Object();
	this._elements[id] = oControl;
    //容器需要加载子节点
    if (oControl.isContainer()) {
        $(oControl.getHTML()).append($(oControl.getElement()).children());
    }
	$(oControl.getElement()).after(oControl.getHTML());
    $(oControl.getElement()).detach();
}

/**
 * 加载动态创建的控件
 */
Container.prototype.appendElement = function(oControl) {
	oControl.setParent(this);
    oControl.setRoot(this.getRoot());
    oControl.setComponent(this.getComponent());
    
	var id = oControl.getAttribute().id;
	if (!this._elements) this._elements = new Object();
	this._elements[id] = oControl;
	$(this.getHTML()).append(oControl.getHTML());
}

/**
 * 移除控件
 * @param {} oControl
 */
Container.prototype.removeElement = function(oControl){
	//如果是组件,需要卸载
	if (oControl.getType() == "Component") {
		oControl.unload();
	}
	var id = oControl.getAttribute().id;
	delete this.getElements()[id];
	$(oControl.getHTML()).remove();
}

/**
 * 删除所有元素
 * @param {} oControl
 */
Container.prototype.removeAllElement = function(){
	for (var id in this.getElements()) {
		var oControl = this.getElements()[id];
		//如果是组件,需要卸载
		if (oControl.getType() == "Component") {
			oControl.unload();
		}
		$(oControl.getHTML()).remove();
		delete oControl;
	}
}

Container.prototype.getElements = function() {
	return this._elements;
}

/**
 * 建立数据单元
 * @param {} oControl
 */
Container.prototype.buildDataUnit = function(oControl) {
	if (!oControl.getAttribute().path) return;
	var value = oControl.getAttribute().path;
	var pt = oControl.getParent();
	var found = false;
	while(pt) {
		if(pt._dataModel){
			found = true;
			oControl._form = pt;
            oControl._dataUnit = new DataUnit(value, oControl);
            pt._dataModel.addUnit(oControl._dataUnit);
            break;
		}
		pt = pt._parent;
	}
}

/**
 * 通过id属性获得控件节点
 */
Container.prototype.getElementById = function(id){
	var ce = this.getElements();
	//遍历组件下所有容器（不包括组件）
	return this.foundElementById(ce, id);
}

Container.prototype.foundElementById = function(ce,id){
	if(ce[id]){
		return ce[id];
	}else{
		for(var i in ce){
			if(ce[i] && ce[i].getElements){
				ca = ce[i].getElements();
				if (!ca) continue;
				var ci = this.foundElementById(ca,id);
				if(ci != null){
					return ci;
				}
			}
		}
	}
	return null;
}

/**
 * 通过path属性获得控件
 */
Container.prototype.getElementByPath = function (path) {
	var dataModel = this.getDataModel();
	if(dataModel != undefined){
		var dataUnits = dataModel.getUnits();
		for(var i = 0;i < dataUnits.length; i++){
			var unit = dataUnits[i];
			if(unit.getTag() == path) {
				return unit.getControl();
			}
		}
	}
	return null;
}


/**
 * 通过控件类型属性获得控件
 */
Container.prototype.getElementByType = function (type) {
	var ce = this.getElements();
	var result = new Array();
	this.foundElementByType(ce, type, result);
    return result;
}

/**
 * 迭代寻找控件类型
 * @param {} ce
 * @param {} type
 * @return {}
 */
Container.prototype.foundElementByType = function(ce, type, result){
	for(var i in ce){
		if (ce[i].getType() == type) {
			result.push(ce[i]);
		}
		if (ce[i].getType && ce[i].getType() == "Component") continue;
		if (ce[i].isContainer()) {
            this.foundElementByType(ce[i].getElements(), type, result);
        }
	}
}

/**
 * 通过控件自定义属性获得控件
 * @params type 自定义属性名字
 */
Container.prototype.getElementByAttribute = function (type) {
	var ce = this.getElements();
	var result = new Array();
	this.foundElementByAttribute(ce, type, result);
    return result;
}

/**
 * 迭代寻找有自定义属性的控件
 * @param {} ce
 * @param {} type
 * @return {}
 */
Container.prototype.foundElementByAttribute = function(ce, type, result){
	for(var i in ce){
		if (ce[i].hasAttribute(type)) {
			result.push(ce[i]);
		}
		if (ce[i].getType && ce[i].getType() == "Component") continue;
		if (ce[i].isContainer()) {
            this.foundElementByAttribute(ce[i].getElements(), type, result);
        }
	}
}

/**
 * 是否拥有组件
 */
Container.prototype.hasOwnerComponent = function(path) {
	var oComps = this.getElementByType("Component");
    for (var i = 0 ; i < oComps.length ; i++) {
        if (oComps[i].getPath() == path) {
        	return true;
        }
    }
    return false;
}

/**
 * 获得组件
 */
Container.prototype.getComponentByPath = function(path) {
	var oComps = this.getElementByType("Component");
    for (var i = 0 ; i < oComps.length ; i++) {
        if (oComps[i].getPath() == path) {
        	return oComps[i];
        }
    }
    return null;
}


/**
 * 获得数据模型
 */
Container.prototype.getDataModel = function(){
	return this._dataModel;
}

/**
 * 往容器里增加一个控件. 
 */
Container.prototype.addItem = function(sType, oAttr){
	var oControl = Control.newInstance(sType, oAttr);
    oControl.setParent(this);
    oControl.setRoot(this.getRoot());
    oControl.setComponent(this.getComponent());
    oControl.init();
    this.addElement(oControl);
    this.addHTML(oControl);
    oControl.initLoad();
    //IE8需要重新绑定事件
    if (!$.support.leadingWhitespace) {
    	oControl.rebuildEvent();
    }
    this.buildDataUnit(oControl);
	return oControl;
}

Container.prototype.addHTML = function(oControl) {
	$(this.getHTML()).append(oControl.getHTML());
}

/**
 * 往容器里删除一个控件
 * @param {Object} oControl
 */
Container.prototype.delItem = function(oControl){
	//如果是组件,需要卸载
	if (oControl.getType() == "Component") {
		oControl.unload();
	}
	var id = oControl.getAttribute().id;
	delete this.getElements()[id];
	$(oControl.getHTML()).remove();
}

/**
 * 清空容器所有对象
 */
Container.prototype.clearItems = function() {
	for (var id in this.getElements()) {
		var oControl = this.getElements()[id];
		this.delItem(oControl);
	}
}

/**
 * 获得数据
 * @return {}
 */
Container.prototype.getData = function() {
	return this.getDataModel().getData();
}

/**
 * 获得数据库查询绑定的值
 * @return {}
 */
Container.prototype.getRecord = function() {
	return this.getDataModel().getRecord();
}

/**
 * 认证整个表单，返回是否通过
 * @return {}
 */
Container.prototype.checkValidate = function() {
	return this.getDataModel().checkValidate();
}

/**
 * 保存表单
 * @param {} bAsync 是否异步，默认为false
 * @param {} oCallBack  异步回调方法
 * @param {} toBody 提交数据到body中，主要解决复杂数据问题.
 * @return {Boolean} 失败返回false, 成功返回服务器的值
 */
Container.prototype.saveForm = function(url, bAsync, oCallBack, toBody) {
	var flag = this.checkValidate();
	if (!flag) { //认证不通过
		return false;
	}
    if (url && url != "") this.getDataSource().setURL(url);
    else this.getDataSource().setURL(this.getAttribute().datasource);

	var oData = this.getData();
	if (bAsync) {
		this.getDataSource().commitDataAsync(oData, oCallBack, toBody);
	} else {
        var oResult = this.getDataSource().commitData(oData, toBody);
        if (!oResult || oResult.error) {
            return false;
        }
        //保存后不提醒内容修改
        this.initForm(oData);
        return oResult;
	}
}

/**
 * 删除数据
 * @param {} bUnConfirm true 不提示直接删除。默认false
 * @param {} bAsync
 * @param {} oCallBack
 */
Container.prototype.deleteForm = function(url, bUnConfirm, bAsync, oCallBack) {
	if (!bUnConfirm) {
		if(!confirm("是否确定删除数据？")){
			return false;
		}
	}
    if (url && url != "") this.getDataSource().setURL(url);
    else this.getDataSource().setURL(this.getAttribute().datasource);
	var oData = this.getData();
	if (bAsync) {
		this.getDataSource().commitDataAsync(oData, oCallBack);
	} else {
		var oResult = this.getDataSource().commitData(oData);
		if (!oResult || oResult.error) {
			return false;
		}
		return oResult;
	}
}

/**
 * 清空表单
 */
Container.prototype.clearForm = function(){
	this.getDataModel().unbind();
}

/**
 * 初始化表单
 * @param {Object} data 初始化值，要求该对象必须存在path,value,attr 3个属性
 */
Container.prototype.initForm = function(oData) {
	this.getDataModel().unbind();
	this.getDataModel().bind(oData);
}

/**
 * 查询和绑定表单值
 * @param {Object} url 请求服务器地址
 * @param {Object} oParam
 * @param {Boolean} bAsync 是否异步加载。默认为false
 * @param {Function} oCallBack 异步加载完成回调方法
 */
Container.prototype.queryForm = function(url, oParam, bAsync, oCallBack) {
	this.getDataModel().unbind();
	var othis = this;
    var oRequest = {rownum:1,start:1,params:oParam}
    if (url && url != "") this.getDataSource().setURL(url);
    else this.getDataSource().setURL(this.getAttribute().datasource);
	if (bAsync) {
		this._oDS.queryData(oRequest, true, function(oResult){
            var oRecords = oResult.records;
			if (oRecords && oRecords.length > 0) {
				othis.getDataModel().bind(oRecords[0]);
			} 
			if(oCallBack) {
				oCallBack(oRecords);
			}
		});
	} else {
		var oResult = this.getDataSource().queryData(oRequest);
        var oRecords = oResult.records;
		if (oRecords.length > 0) {
			this.getDataModel().bind(oRecords[0]);
		}
	}
}

/**
 * 后台直接返回JavaBean对象的方式. 后台直接接受查询参数
 * @param {} url
 * @param {} oParam
 * @param {} bAsync
 * @param {} oCallBack
 */
Container.prototype.queryFrom2 = function(url, oParam, bAsync, oCallBack) {
	this.getDataModel().unbind();
	if (!url || url == "") url = this.getDataSource().getURL();
	var othis = this;
	var soap = new HWSOAP(url);
	if (bAsync) {
		soap.send(oParam, true, oCallBack);
	} else {
		soap.send(oParam);
	}
	var oResult = soap.getResult();
	this.setValue(oResult);
}

/**
 * 设置为不可编辑
 * @param {Boolean} state 是否设置所有控件不可用。
 * 默认为false(只设置有path属性的控件不可编辑).
 */
Container.prototype.setDisable = function(state) {
	if (!state) {
		var oDataModel = this.getDataModel();
		if (oDataModel) {
			oDataModel.setDisable();
		}
	} else {
		var oElements  = this.getElements();
		for (var i in oElements) {
			oElements[i].setDisable(state);
		}
	}
	this._disable = true;
}

/**
 * 设置为可编辑
 */
Container.prototype.setEnable = function(){
	var oElements  = this.getElements();
	for (var i in oElements) {
		oElements[i].setEnable();
	}
	this._disable = false;
}

/**
 * 设置为只读
 */
Container.prototype.setReadonly = function() {
	var oElements  = this.getElements();
	for (var i in oElements) {
		oElements[i].setReadonly();
	}
	this._readonly = true;
}

/**
 * 取消只读
 */
Container.prototype.setDisReadonly = function(){
	var oElements  = this.getElements();
	for (var i in oElements) {
		oElements[i].setDisReadonly();
	}
	this._readonly = false;
}

Container.prototype.getValue = function() {
    return this.getData();
}

Container.prototype.setValue = function(oData) {
    this.initForm(oData);
}

Container.prototype.getRowNum = function() {
	return this._rownum;
}

/**
 * 设置容器作为表格的行号。
 * @param {} rownum
 */
Container.prototype.setRowNum = function(rownum) {
	this._rownum = rownum;
}

Container.prototype.getRowID = function() {
	return this._rowid;
}

/**
 * 设置容器作为表格的行id。
 * @param {} rownum
 */
Container.prototype.setRowID = function(rowid) {
	this._rowid = rowid;
}

/**
 * 异步加载, 容器内显示等待
 */
Container.prototype.beginLoad = function(msg) {
	if (!this._loadingDom) this.createLoadDom(msg);
	var position = $(this.getHTML()).css("position");
	if (position != "absolute" && position != "fixed") {
		$(this.getHTML()).css({
			"position":"relative"
		});
	}
	$(this.getHTML()).append(this._loadingDom);
}

/**
 * 结束加载, 取消等待
 */
Container.prototype.endLoad = function() {
	$(this._loadingDom).detach();
}

/**
 * 创建加载节点
 */
Container.prototype.createLoadDom = function(msg) {
    msg = msg ? msg : "加载中...";
	var loadingDom = $(
        "<div class='contloading'>" +
            "<div class='loading'>" + msg + "</div>" +
        "</div>");
    var cw = $(this._html).width();
    var ch = $(this._html).height();
//    if (cw == 0) cw = document.documentElement.clientWidth;
//    if (ch == 0) ch = document.documentElement.clientHeight;

    var offset = $(this._html).offset();
    $(loadingDom).css({
        left:0,
        top:0
    });
    $(loadingDom).width(cw);
    $(loadingDom).height(ch);
    $(".loading", loadingDom).css({
        left:(cw-80)/2,
        top:(ch-40)/2
    });
    this._loadingDom = loadingDom;
}

/**
 * 设置数据模型path属性
 * @param {} path
 */
Container.prototype.setPath = function(path) {
	this.getAttribute().path = path;
	if (this._dataUnit) {
		this._dataUnit.setTag(path);
	}
}

/**
 * 判断是否修改
 * @return {}
 */
Container.prototype.hasModify = function() {
	return this.getDataModel().hasModify();
}